package org.yhx.learning.verticle;/*
 * Copyright (C), 2024, bigmoon
 * FileName:
 * Author:   bigmoon
 * Date:     2024/9/4 16:17
 * Description: //模块目的、功能描述
 * History: //修改记录
 * &lt;author&gt;      &lt;time&gt;      &lt;version&gt;    &lt;desc&gt;
 * 修改人姓名             修改时间            版本号                  描述
 */

import io.vertx.core.*;
import io.vertx.core.json.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 工作 verticl 支持堵塞任务
 * 或者是blocking
 * 通过设置.setWorker(true) 使得 verticle可以执行blocking 任务。
 * 但是blocking任务可能在不同线程中使用
 * 但将阻塞代码提取到 Worker Verticle 中可能并不总是有意义。 这样做会导致执行小任务的Worker Verticle 类的数量激增，并且每个类可能无法形成一个合理的独立功能单元。
 * 可以参考下Blocking
 *  执行方法是用work pool， resultHandle 是eventloop方法
 *
 *  连续的 executeBlocking 操作的结果处理顺序与调用 executeBlocking 的顺序相同。 executeBlocking 有一个带有附加 boolean 参数的变体，当它设置为 false 时，无论executeBlocking 的顺序如何，只要它们可用，结果都会作为事件循环事件在其可用时立即被提供
 */
public class WorkVerticle extends AbstractVerticle {

    private static final Logger LOGGER = LoggerFactory.getLogger(WorkVerticle.class);


    @Override
    public void start() throws Exception {
        vertx.setPeriodic(10_000,(id)->{


            //blocking 内容尽量不在这里执行，可以通过blocking实现
//            LOGGER.info("Zzzzzz");
//            try {
//                Thread.sleep(700);
//                LOGGER.info("wake up!");
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            LOGGER.info("over");

            vertx.executeBlocking(this::blockingCodeHandler,this::handler);
        });
    }

    private void blockingCodeHandler(Promise<JsonObject> promise){
        LOGGER.info("Blocking code running");
        try {
            Thread.sleep(4000);
            LOGGER.info("Done!");
            promise.complete(new JsonObject().put("result","ok"));  // <3>
        } catch (InterruptedException e) {
            promise.fail(e);
        }
    }

    private void handler(AsyncResult<JsonObject> ar){

        if (ar.succeeded()) {
            LOGGER.info("Blocking code result: {}", ar.result());
        } else {
            LOGGER.error("Woops", ar.cause());
        }
    }

    public static void main(String[] args) {

        Vertx.vertx().deployVerticle(new WorkVerticle());
    }
}
